package produce

import (
	"data-process/config"
	"data-process/logger"
	"data-process/parsing"
)

type MockProduce struct {
	Produce
	FieldDataPool map[string][]interface{} // 各个属性产生数据的池子
	Model         map[string]interface{}
}

func DefaultMockProduce() *MockProduce {
	p := config.SysConfig.Produce
	return NewMockProduce(p.Type, p.Model, config.SysConfig.Size)
}

func NewMockProduce(clazz string, model map[string]interface{}, size int) *MockProduce {
	m := new(MockProduce)
	m.Model = model
	m.Produce = Produce{
		Type:      clazz,
		Size:      size,
		DataPool:  make(chan map[string]interface{}, 10),
		ModelKeys: make([]string, 0),
		producer:  m.producer,
	}
	m.simpleParse()
	return m
}

// simpleParse 简单解析：将模型属性的类型确定分配到指定的解析器去解析
// 遍历属性，对其解析并构建指定的测试数据返回
// 最后将各个属性汇总生成一条数据发送到channel中
func (m *MockProduce) simpleParse() {
	if len(m.Model) <= 0 {
		logger.Error("需要被解析的模型不存在")
		return
	}
	m.FieldDataPool = make(map[string][]interface{}, len(m.Model))
	// 防止key遍历的时候乱序的问题这里提取key，方便后面顺序写入数据
	for k, v := range m.Model {
		// 这里通过遍历属性，对其解析并构建指定的测试数据返回
		logger.Infof("需要被解析的模型是：%s => %v\n", k, v)
		key, build, err := parsing.NewParsing(k, v, m.Size).ParseFactory().Build()
		if err != nil {
			logger.Fatal("模型解析出现错误")
			return
		}
		m.FieldDataPool[key] = build
		m.ModelKeys = append(m.ModelKeys, key)
		// 暂时输出数据
		//logger.Infof("解析获取的数据：%v", build)
	}
}

// producer 生成数据
func (m *MockProduce) producer() {
	//m.simpleParse()
	logger.Infof("将数据池中的数据组合构建")
	sum := len(m.FieldDataPool)
	if sum <= 0 || sum != len(m.Model) {
		logger.Error("解析数据失败")
		return
	}
	for i := 0; i < m.Size; i++ {
		item := make(map[string]interface{}, sum)
		for k, v := range m.FieldDataPool {
			item[k] = v[i]
		}
		logger.Infof("构建第%d条数据：%v\n", i, item)
		m.DataPool <- item
	}
	logger.Infof("生成%d条数据关闭通道", m.Size)
	defer func() {
		m.wg.Done()
		close(m.DataPool)
	}()
}
